class Observer {
    constructor(data){
        this.walk(data)
    }

    walk(data){
        if(data && typeof data === 'object'){
            // 对象会循环里面的属性
            Object.keys(data).forEach(key=>{
                this.defineReactive(data,key,data[key])
                this.walk(data[key])
            })
            // 数组会循环里面的元素，但不会处理里面的属性
            // 这就是arr[0] = 1，arr.length = 0不会响应式更新dom的原因
            // 为什么不处理里面的属性？因为给每一个下标和属性都给响应式的话，这可能会影响性能
        }
    }

    defineReactive(data,key,val){
        let dep = new Dep()
        Object.defineProperty(data,key,{
            enumerable: true,
            configurable: true,
            get:()=>{
                // 收集watcher
                Dep.target && dep.addSub(Dep.target)
                return val
            },
            set:v=>{
                // console.log('set:',v,val);
                if(v === val) return
                val = v
                // 设置值之后得重新把它变成响应式的
                this.walk(v)

                // 发送通知
                dep.notify()
            }
        })
    }
}